package com.wxy.ideaplugin.field;

import com.intellij.ide.highlighter.XmlFileType;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.FileTypeIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.psi.xml.XmlTagValue;
import com.wxy.ideaplugin.utils.SwitchLineCamel;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

public class FieldManager {
    public void addMethod(AnActionEvent e, String columnName, String columnType, String columnDesc) {
        final PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE);
        String beanName = psiFile.getName().replaceAll(".java", "");
        String propertyName = SwitchLineCamel.switch2Property(columnName);
        String propertyLabel = columnDesc;
        String propertyType0 = "String";
        if (columnType.startsWith("varchar")) {
            propertyType0 = "String";
        }else if (columnType.startsWith("int")) {
            propertyType0 = "Integer";
        }else if (columnType.startsWith("bigint")) {
            propertyType0 = "Long";
        }else if (columnType.startsWith("datetime") || columnType.startsWith("date") || columnType.startsWith("timestamp")) {
            propertyType0 = "Date";
        }
        String propertyType = propertyType0;

        //DTO
        PsiFile psiFileDto = psiFile.getParent().getParent().findSubdirectory("dto").findFile(beanName+"Dto.java");

        //XML
        List<VirtualFile> virtualFiles = FileTypeIndex.getFiles(XmlFileType.INSTANCE, GlobalSearchScope.allScope(e.getProject())).stream().collect(Collectors.toList());
        VirtualFile virtualFile = null;
        for(VirtualFile virtualFile1:virtualFiles) {
            if (virtualFile1.getName().equals(beanName+"Mapper.xml")) {
                virtualFile = virtualFile1;
                break;
            }
        }
        PsiFile psiFileXml1 = PsiManager.getInstance(e.getProject()).findFile(virtualFile);
        XmlFile psiFileXml = (XmlFile)psiFileXml1;

        //vue
        VirtualFile virtualFileVue = e.getProject().getProjectFile().getParent().getParent().findFileByRelativePath("/lowcode-ui/src/views/coding/flow/oa2/chatai/chatai/")
                .findChild("list.vue");
        PsiFile psiFileVue = PsiManager.getInstance(e.getProject()).findFile(virtualFileVue);

        (new WriteCommandAction.Simple(e.getProject(), new PsiFile[]{psiFile, psiFileDto, psiFileXml, psiFileVue}) {
            protected void run() throws Throwable {
                String methodText = "private ###propertyType### ###propertyName###;";
                System.out.println(methodText);
                methodText = methodText.replaceAll("###propertyName###", propertyName);
                methodText = methodText.replaceAll("###propertyType###", propertyType);
                System.out.println(methodText);

                //bean
                if (psiFile!=null) {
                    PsiElementFactory elementFactoryBean = JavaPsiFacade.getElementFactory(psiFile.getProject());
                    PsiField psiField = elementFactoryBean.createFieldFromText(methodText, psiFile);
                    PsiClass psiClass = PsiTreeUtil.getChildOfType(psiFile, PsiClass.class);
                    psiClass.add(psiField);
                }

                //dto
                if (psiFileDto!=null) {
                    PsiElementFactory elementFactoryDto = JavaPsiFacade.getElementFactory(psiFileDto.getProject());
                    //PsiMethod toMethod2 = elementFactoryDto.createMethodFromText(methodText, psiFileDto);
                    PsiField psiField = elementFactoryDto.createFieldFromText(methodText, psiFile);
                    PsiClass psiClass = PsiTreeUtil.getChildOfType(psiFileDto, PsiClass.class);
                    psiClass.add(psiField);
                }

                //mapper.xml
                if (psiFileXml!=null) {
                    //xml resultMap
                    String thisXml = "<result column=\"###columnName###\" property=\"###propertyName###\" />";
                    thisXml = thisXml.replaceAll("###columnName###", columnName);
                    thisXml = thisXml.replaceAll("###propertyName###", propertyName);
                    System.out.println(thisXml);
                    XmlElementFactory elementFactoryXml = XmlElementFactory.getInstance(psiFileXml.getProject());
                    XmlTag newTag = elementFactoryXml.createTagFromText(thisXml);
                    psiFileXml.getDocument().getRootTag().findFirstSubTag("resultMap").addSubTag(newTag, false);
                    //xml sql
                    XmlTagValue xmlTagValue = psiFileXml.getDocument().getRootTag().findFirstSubTag("sql").getValue();
                    String oldText = xmlTagValue.getText();
                    oldText = oldText.substring(0, oldText.lastIndexOf("\n"));
                    StringBuilder sb = new StringBuilder();
                    sb.append(oldText);
                    sb.append(",\n");
                    sb.append(columnName);
                    sb.append("\n");
                    System.out.println(sb.toString());
                    xmlTagValue.setText(sb.toString());
                }

                //vue
                if (psiFileVue!=null) {
                    String thisVueText =
                            "<el-table-column label=\"###propertyLabel###\" prop=\"###propertyName###\" align=\"center\" min-width=\"80\"> \n" +
                                    "      <template slot-scope=\"{row}\"> \n" +
                                    "       <span>{{ row.###propertyName### }}</span> \n" +
                                    "      </template> \n" +
                                    "     </el-table-column> ";
                    thisVueText = thisVueText.replaceAll("###propertyLabel###", propertyLabel);
                    thisVueText = thisVueText.replaceAll("###propertyName###", propertyName);
                    System.out.println(thisVueText);
                    String vueText = FileDocumentManager.getInstance().getDocument(virtualFileVue).getText();
                    Document docVue = Jsoup.parse(vueText);
                    docVue.select("#rowOptBtn").before(thisVueText);
                    String vueTextNew = docVue.html();
                    FileDocumentManager.getInstance().getDocument(virtualFileVue).setText(vueTextNew);
                }
            }
        }).execute();
    }


    /*private PsiClass getPsiClass(AnActionEvent e) {
        PsiElement elementAt = this.getPsiElement(e);
        return elementAt == null?null:(PsiClass) PsiTreeUtil.getParentOfType(elementAt, PsiClass.class);
    }
    private PsiElement getPsiElement(AnActionEvent e) {
        PsiFile psiFile = (PsiFile)e.getData(LangDataKeys.PSI_FILE);
        Editor editor = (Editor)e.getData(PlatformDataKeys.EDITOR);
        if(psiFile != null && editor != null) {
            int offset = editor.getCaretModel().getOffset();
            return psiFile.findElementAt(offset);
        } else {
            e.getPresentation().setEnabled(false);
            return null;
        }
    }*/

}
